package com.agileai.portal.controller.base;

import java.util.List;

import javax.servlet.ServletContext;

import com.agileai.common.KeyGenerator;
import com.agileai.domain.DataParam;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.DispatchRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.portal.bizmoduler.SecurityAuthorizationConfig;
import com.agileai.portal.bizmoduler.base.LayoutBuilder;
import com.agileai.portal.bizmoduler.base.PageManage;
import com.agileai.portal.driver.AttributeKeys;
import com.agileai.portal.driver.model.LayoutContainer;
import com.agileai.portal.driver.model.MenuBar;
import com.agileai.portal.driver.model.MenuItem;
import com.agileai.portal.driver.model.Page;
import com.agileai.portal.driver.model.PortletWindowConfig;
import com.agileai.portal.driver.service.DriverConfiguration;
import com.agileai.portal.driver.service.PageProvider;
import com.agileai.portal.driver.service.PortalConfigService;

public class LayoutManageHandler extends BaseHandler{
	public static final String PAGE_SESSION_KEY = "CURRENT_CONFIG_PAGE";
	public static final String LAYOUT_HTML_KEY = "CURRENT_LAYOUT_HTML";
	public static final String DROPPABLE_SCRIPT_KEY = "DROPPABLE_SCRIPT";
	public static final String CONTAINER_ID = "containerId";
	public static final String PORTLET_ID = "portletId";
	public static final String PORTLET_APP_ID = "portletAppId";
	public static final String PORTLET_APP_NAME = "portletAppName";
	public static final String PORTLET_APP_TITLE = "portletAppTitle";
	public static final String CHILD_CONTAINER_NUM = "childNumber";
	public static final String SPLIT_CONTAINER_NUM = "splitNumber";
	public static final String CHILD_WIDTH_HTML = "childWidth";
	
	private boolean isFinded = false;
	
	private PortalConfigService getPortalConfigService(ServletContext servletContext){
		DriverConfiguration driverConfiguration = (DriverConfiguration)servletContext.getAttribute(AttributeKeys.DRIVER_CONFIG);
		return driverConfiguration.getPortalConfigService();
	}
	
	private void setupPageAttributes(DataParam param,Page page){
		StringBuffer html = new StringBuffer();
		String menuId = page.getMenuId();
		PortalConfigService portalConfigService = getPortalConfigService(this.getDispatchServlet().getServletContext());
		MenuItem menuItem = portalConfigService.getMenuItem(menuId);
		MenuBar menuBar = menuItem.getMenuBar();
		boolean belongLoginedNavigater = MenuBar.Type.LOGIN_AFTER.equals(menuBar.getType());
		LayoutBuilder layoutBuilder = new LayoutBuilder(belongLoginedNavigater);
		layoutBuilder.buildLayoutHtml(page, html);
		this.setAttributes(param);
		setAttribute(LAYOUT_HTML_KEY,html.toString());
	}
	public ViewRenderer prepareDisplay(DataParam param){
		this.getSessionAttributes().remove(PAGE_SESSION_KEY);
		PageProvider pageProvider = (PageProvider)this.lookupService("pageProvider");
		String pageId = param.get("PAGE_ID");
		Page page = pageProvider.buildPage(pageId);
		if (page.getLayoutContainers().isEmpty()){
			this.initEmptyLayout(page);
		}
		this.setAttribute(param, "NAV_ID");
		this.putSessionAttribute(PAGE_SESSION_KEY, page);
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	private void initEmptyLayout(Page page){
		LayoutContainer layoutContainer0 = page.createLayoutContainer();
		layoutContainer0.setId(KeyGenerator.instance().genKey());
		if (LayoutContainer.ContainerType.COLUMN.equals(layoutContainer0.getContainerType())){
			layoutContainer0.setWidth("50%");
		}
		LayoutContainer layoutContainer1 = page.createLayoutContainer();
		layoutContainer1.setId(KeyGenerator.instance().genKey());
		if (LayoutContainer.ContainerType.COLUMN.equals(layoutContainer1.getContainerType())){
			layoutContainer1.setWidth("50%");
		}
	}
	public ViewRenderer doSaveAction(DataParam param){
		PageManage pageManage = lookupService(PageManage.class);
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		pageManage.savePageLayouts(page,false);
		String pageId = page.getPageId();
		PortalConfigService portalConfigService = (PortalConfigService)this.lookupService("PortalConfigService");
		portalConfigService.refreshPorletConfig(true,pageId);
		String rspText = "保存布局信息成功！";
		return new AjaxRenderer(rspText);
	}
	public ViewRenderer doCopyPageAction(DataParam param){
		String selectPageId = param.get("selectPageId");
		String currentPageId = param.get("currentPageId");
		PageProvider pageProvider = (PageProvider)this.lookupService("pageProvider");
		Page sourcePage = pageProvider.buildPage(selectPageId);
		Page targetPage = pageProvider.buildPage(currentPageId);
		String rspText = "";
		try {
			this.generateGrid8PortletId(targetPage,sourcePage,currentPageId);
			
			PageManage pageManage = lookupService(PageManage.class);
			pageManage.savePageLayouts(targetPage,true);
			
			PortalConfigService portalConfigService = (PortalConfigService)this.lookupService("PortalConfigService");
			portalConfigService.refreshPorletConfig(true,currentPageId);
			portalConfigService.refreshPorletConfig(true,selectPageId);
			rspText = "复制页面成功！";
		} catch (Exception e) {
			rspText = e.getLocalizedMessage();
		}
		return new AjaxRenderer(rspText);
	}
	private void generateGrid8PortletId(Page targetPage,Page sourcePage,String currentPageId ){
		targetPage.setPageId(currentPageId);
		targetPage.getLayoutContainers().clear();
		targetPage.getLayoutContainers().addAll(sourcePage.getLayoutContainers());
		
		List<LayoutContainer> layoutContainers = targetPage.getLayoutContainers();
		for (int i=0;i < layoutContainers.size();i++){
			LayoutContainer layoutContainer = layoutContainers.get(i);
			layoutContainer.setId(KeyGenerator.instance().genKey());
			
			List<PortletWindowConfig> portletWindowConfigs = layoutContainer.getPortlets();
			for (int j =0; j < portletWindowConfigs.size();j++){
				PortletWindowConfig config = portletWindowConfigs.get(j);
				config.setId(KeyGenerator.instance().genKey());
			}
			if (!layoutContainer.getChildContainerList().isEmpty()){
				this.generateChildGrid8PortletId(layoutContainer.getChildContainerList());				
			}
		}
	}
	
	private void generateChildGrid8PortletId(List<LayoutContainer> layoutContainers){
		for (int i=0;i < layoutContainers.size();i++){
			LayoutContainer layoutContainer = layoutContainers.get(i);
			layoutContainer.setId(KeyGenerator.instance().genKey());
			
			List<PortletWindowConfig> portletWindowConfigs = layoutContainer.getPortlets();
			for (int j =0; j < portletWindowConfigs.size();j++){
				PortletWindowConfig config = portletWindowConfigs.get(j);
				config.setId(KeyGenerator.instance().genKey());
			}
			if (!layoutContainer.getChildContainerList().isEmpty()){
				this.generateChildGrid8PortletId(layoutContainer.getChildContainerList());				
			}
		}
	}
	
	public ViewRenderer doMovePortletAction(DataParam param){
		String sourceContainerId = param.get("sourceContainerId");
		String targetContainerId = param.get("targetContainerId");
		String portletId = param.get("portletId");
		LayoutContainer sourceLayoutContainer = retrieveLayoutContainer(sourceContainerId);
		isFinded = false;
		LayoutContainer targetLayoutContainer = retrieveLayoutContainer(targetContainerId);
		PortletWindowConfig portletWindowConfig = sourceLayoutContainer.getPortlet(portletId);
		sourceLayoutContainer.removePortlet(portletId);
		targetLayoutContainer.addPortletWindowConfig(portletWindowConfig);
		
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	public ViewRenderer doCancelAction(DataParam param){
		return prepareDisplay(param);
	}
	public ViewRenderer doBackAction(DataParam param){
		String handlerId = getLastHanderId();
		return new DispatchRenderer(this.getHandlerURL(handlerId));
	}
	public ViewRenderer doSetupWidthAction(DataParam param){
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		String containerStyle = param.get("containerStyle");
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		LayoutContainer parentContainer = curLayoutContainer.getParentContainer();
		List<LayoutContainer> childList = null;
		if (parentContainer != null){
			childList = parentContainer.getChildContainerList();
		}else{
			childList = page.getLayoutContainers();
		}
		int childSize = childList.size();
		for (int i=0;i < childSize;i++){
			String childWidth = param.get(CHILD_WIDTH_HTML+i)+"%";
			LayoutContainer tempLayoutContainer = childList.get(i);
			tempLayoutContainer.setWidth(childWidth);				
		}
		curLayoutContainer.setStyle(containerStyle);
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	public ViewRenderer doAddChildContainerAction(DataParam param){
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		int childNumber = param.getInt(CHILD_CONTAINER_NUM);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		
		int sumWidth = 0;
		for (int i=0;i < childNumber;i++){
			LayoutContainer childContainer = curLayoutContainer.createChildLayoutContainer();
			String childContainerId = KeyGenerator.instance().genKey();
			childContainer.setId(childContainerId);
			
			if (LayoutContainer.ContainerType.COLUMN.equals(childContainer.getContainerType())){
				if (i == childNumber-1){
					int width = 100-sumWidth;
					childContainer.setWidth(String.valueOf(width)+"%");
				}else{
					int width = 100/childNumber;
					sumWidth = sumWidth + width;
					childContainer.setWidth(String.valueOf(width)+"%");	
				}
			}
		}
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	LayoutContainer retrieveLayoutContainer(String containerId){
		LayoutContainer result = null;
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		List<LayoutContainer> topContainers = page.getLayoutContainers();
		for (int i=0;i < topContainers.size();i++){
			LayoutContainer layoutContainer = topContainers.get(i);
			if (containerId.equals(layoutContainer.getId())){
				result = layoutContainer;
				isFinded = true;
			}else{
				result = loopLayoutContainer(layoutContainer,containerId);
			}
			if (isFinded){
				break;
			}
		}
		return result;
	}
	private LayoutContainer loopLayoutContainer(LayoutContainer curLayoutContainer,String containerId){
		LayoutContainer result = null;
		List<LayoutContainer> childContainers = curLayoutContainer.getChildContainerList();
		for (int i=0;i < childContainers.size();i++){
			LayoutContainer layoutContainer = childContainers.get(i);
			if (containerId.equals(layoutContainer.getId())){
				result = layoutContainer;
				isFinded = true;
			}else{
				result = loopLayoutContainer(layoutContainer,containerId);
			}
			if (isFinded){
				break;
			}
		}
		return result;
	}
	public ViewRenderer doSplitContainerAction(DataParam param){
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		String containerType = curLayoutContainer.getContainerType();
		LayoutContainer parentContainer = curLayoutContainer.getParentContainer();
		int splitNumber = param.getInt(SPLIT_CONTAINER_NUM);
		for (int i=0;i < splitNumber-1;i++){
			LayoutContainer layoutContainer = null;
			if (parentContainer != null){
				layoutContainer = parentContainer.createChildLayoutContainer(curLayoutContainer);	
			}else{
				layoutContainer = page.createChildLayoutContainer(curLayoutContainer);
			}
			layoutContainer.setId(KeyGenerator.instance().genKey());
			if (LayoutContainer.ContainerType.COLUMN.equals(containerType)){
				String curWidth = curLayoutContainer.getWidth();
				String splitedWidth = this.getSplitedWidth(curWidth, splitNumber);
				layoutContainer.setWidth(splitedWidth);
			}
		}
		if (LayoutContainer.ContainerType.COLUMN.equals(containerType)){
			String curWidth = curLayoutContainer.getWidth();
			String splitedWidth = this.getSplitedWidth(curWidth, splitNumber);
			curLayoutContainer.setWidth(splitedWidth);
		}
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	private String getSplitedWidth(String curWidth,int splitNumber) {
		String temp = curWidth.substring(0,curWidth.length()-1);
		int cc = Integer.parseInt(temp) / splitNumber;
		String result = String.valueOf(cc)+"%";
		return result;
	}
	public ViewRenderer doDeleteContainerAction(DataParam param){
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		LayoutContainer parentContainer = curLayoutContainer.getParentContainer();
		
		if (parentContainer != null){
			parentContainer.removeChildLayoutContainer(containerId);
			restContainerWidth(curLayoutContainer,parentContainer.getChildContainerList());
		}else{
			page.removeChildLayoutContainer(containerId);
			restContainerWidth(curLayoutContainer,page.getLayoutContainers());
		}
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	private void restContainerWidth(LayoutContainer curLayoutContainer,List<LayoutContainer> childList){
		String containerType = curLayoutContainer.getContainerType();
		int childSize = childList.size();
		if (childSize != 0 && LayoutContainer.ContainerType.COLUMN.equals(containerType)){
			String curWidth = "100%";
			String splitedWidth = this.getSplitedWidth(curWidth, childSize);
			for (int i=0;i < childSize;i++){
				LayoutContainer tempLayoutContainer = childList.get(i);
				tempLayoutContainer.setWidth(splitedWidth);				
			}
		}
	}
	public ViewRenderer doAddPortletAction(DataParam param){
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		String portletAppId = param.get(PORTLET_APP_ID);
		String portletAppName = param.get(PORTLET_APP_NAME);
		String portletAppTitle = param.get(PORTLET_APP_TITLE);
		String newPortletId = KeyGenerator.instance().genKey();
		
		PortletWindowConfig pagePortlet = new PortletWindowConfig(newPortletId);
		pagePortlet.setTitle(portletAppTitle);
		pagePortlet.setPortletName(portletAppName);
		pagePortlet.setPortletAppId(portletAppId);
		pagePortlet.setDecoratorId(PortletWindowConfig.DecoratorType.DEFAULT);
		pagePortlet.setHeight(PortletWindowConfig.AUTO_HEIGHT);
		pagePortlet.setStored(false);
		curLayoutContainer.getPortlets().add(pagePortlet);
		
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	public ViewRenderer doMoveUpAction(DataParam param){
		String portletId = param.get(PORTLET_ID);
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		curLayoutContainer.moveUpPortlet(portletId);
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	public ViewRenderer doMoveDownAction(DataParam param){
		String portletId = param.get(PORTLET_ID);
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		curLayoutContainer.moveDownPortlet(portletId);
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}
	
	public ViewRenderer doDelPortletAction(DataParam param){
		String portletId = param.get(PORTLET_ID);
		Page page = (Page)this.getSessionAttribute(PAGE_SESSION_KEY);
		String containerId = param.get(CONTAINER_ID);
		LayoutContainer curLayoutContainer = retrieveLayoutContainer(containerId);
		PortletWindowConfig portletWindowConfig = curLayoutContainer.getPortlet(portletId);
		if (portletWindowConfig.isStored()){
			SecurityAuthorizationConfig authorizationConfig = this.lookupService(SecurityAuthorizationConfig.class);
			authorizationConfig.delPortletAuthRelations(portletId);
		}
		curLayoutContainer.removePortlet(portletId);
		this.setupPageAttributes(param,page);
		return new LocalRenderer(getPage());
	}

}
